package com.wisecoach.gatewayplus.transaction.lockedtx;

/**
 * {@code @author:} wisecoach
 * {@code @date:} 2023/9/26 下午1:57
 * {@code @version:} 1.0.0
 */
public class RWLock implements Cloneable {
    private int readSemaphore;
    private int writeSemaphore;
    private static final RWLock prototype = new RWLock();

    public static RWLock newRWLock() {
        return prototype.clone();
    }

    public boolean tryLock() {
        if (readSemaphore == 0 && writeSemaphore == 0) {
            writeSemaphore += 1;
            return true;
        }
        return false;
    }

    public boolean canLock() {
        return readSemaphore == 0 && writeSemaphore == 0;
    }

    public void unlock() {
        writeSemaphore -= 1;
    }

    public boolean tryRLock() {
        if (writeSemaphore == 0) {
            readSemaphore += 1;
            return true;
        }
        return false;
    }

    public boolean canRLock() {
        return writeSemaphore == 0;
    }

    public void unRLock() {
        readSemaphore -= 1;
    }

    @Override
    public RWLock clone() {
        try {
            RWLock clone = (RWLock) super.clone();
            return clone;
        } catch (CloneNotSupportedException e) {
            throw new AssertionError();
        }
    }
}
